#pragma once

namespace LSH
{

#pragma warning(disable:4521)
#pragma warning(disable:4522)

template<typename T>
class Singleton
{
public:
	inline static void create(){ assert(NULL == _pInstance); _pInstance = new T; }
	inline static void destory(){ delete _pInstance; _pInstance = NULL; }
public:
	inline static T&   getSingleton(){ assert(_pInstance); return *_pInstance; }
	inline static T*   getSingletonPtr(){ assert(_pInstance); return _pInstance; }
protected:
    Singleton() {};
    virtual ~Singleton() {};
protected:
	static T* _pInstance;
};

//------------------------------------------------------------------------
#define  DESCLARE_SINGLETON(className) \
	public:	\
		static void create(); \
		static void destroy(); \
	public: \
		static className& getSingleton(); \
		static className* getSingletonPtr(); \
	protected: \
		className(); \
		virtual ~className(); \
		className(className& obj); \
		className(const className& obj); \
		className& operator = (className& obj); \
		className&  operator = (const className& obj); \
	protected: \
		static className* _pInstance;

//------------------------------------------------------------------------
#define IMPLEMENT_SINGLETON(className) \
	className* className::_pInstance = NULL; \
	void className::create(){ \
		assert(NULL == _pInstance); \
		_pInstance = new className; \
	} \
	void className::destroy(){ \
		assert(NULL != _pInstance); \
		delete _pInstance; \
		_pInstance = NULL; \
	} \
	className& className::getSingleton(){ \
		assert(_pInstance); \
		return *_pInstance; \
	} \
	className* className::getSingletonPtr(){ \
		assert(_pInstance); \
		return _pInstance; \
	} \
	className&  className::operator = (className& obj) { return *_pInstance; } \
	className&  className::operator = (const className& obj) { return *_pInstance; }

} // LSH
